App.require(["matrix3"], function (matrix3) {
    var Matrix3 = matrix3.Matrix3;
    App.defineWidget("polyline", {
        render: function (ctx) {
            ctx.save();
            var style = this.style;
            ctx.translate(style.x, style.y);
            ctx.strokeStyle = style.stroke;
            ctx.lineWidth = style.linewidth;
            ctx.beginPath();
            var points = style.points;
            ctx.moveTo(points[0], points[1]);
            for (var i = 2; i < points.length; i += 2) {
                ctx.lineTo(points[i], points[i + 1]);
            }
            ctx.stroke();
            ctx.restore();
        },
        _parentInverse: function (pos) {
            var matrix = Matrix3.inverseOf(this.getParentMatrix());
            var e = matrix.elements;
            return {
                x: e[0] * pos.x + e[3] * pos.y + e[6],
                y: e[1] * pos.x + e[4] * pos.y + e[7]
            }
        },
        _inverse: function (pos) {
            var matrix = Matrix3.inverseOf(this.getMatrix());
            var e = matrix.elements;
            return {
                x: e[0] * pos.x + e[3] * pos.y + e[6],
                y: e[1] * pos.x + e[4] * pos.y + e[7]
            }
        },
        getMatrix: function () {
            var parentMatrix = this.getParentMatrix();
            var currentMatrix = Matrix3.fromTranslation(this.x, this.y);
            return Matrix3.multiply(parentMatrix, currentMatrix);
        },
        getParentMatrix: function () {
            if (!this.parent || this.parent.constructor === App.Scene) return new Matrix3();
            return this.parent.getMatrix();
        },
        style: {
            x: 20,
            y: 20,
            points: [ 20.5, 20.5, 20.5, 80.5 ],
            stroke: "black",
            linewidth: 1
        },
        get stroke() {
            return this.style.stroke;
        },
        set stroke(value) {
            this.style.stroke = value;
            this.getScene().nextRender();
        },
        get points() {
            return this.style.points;
        },
        set points(value) {
            this.style.points = value;
            this.getScene().nextRender();
        },
        set x(value) {
            this.style.x = value;
            this.getScene().nextRender();
        },
        get x() {
            return this.style.x;
        },
        get y() {
            return this.style.y;
        },
        set y(value) {
            this.style.y = value;
            this.getScene().nextRender();
        }
    })
})